package com.yanfan.energy.service.impl;

import cn.hutool.core.util.StrUtil;
import com.yanfan.common.core.domain.model.LoginUser;
import com.yanfan.common.utils.SecurityUtils;
import com.yanfan.common.utils.bean.BeanUtils;
import com.yanfan.energy.domain.*;
import com.yanfan.energy.domain.enums.SegmentStateStatus;
import com.yanfan.energy.domain.enums.TimeDimensionEnum;
import com.yanfan.energy.mapper.BatchSegmentationDao;
import com.yanfan.energy.mapper.BatchesDao;
import com.yanfan.energy.service.BatchSegmentationService;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 生产记录表(BatchSegmentation)表服务实现类
 *
 * @author makejava
 * @since 2023-01-09 18:34:29
 */
@Service("batchSegmentationService")
public class BatchSegmentationServiceImpl implements BatchSegmentationService {
    @Resource
    private BatchSegmentationDao batchSegmentationDao;

    @Resource
    private BatchesDao batchesDao;

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
    @Override
    public BatchSegmentation queryById(Long id) {
        BatchSegmentation batchSegmentation = this.batchSegmentationDao.queryById(id);
        if (batchSegmentation == null) {
            return batchSegmentation;
        }
        Map<Long, String> factoryMap = queryFactoryMap();
        Map<Long, String> workShopMap = queryWorkShopMap();
        batchSegmentation.setStateName(SegmentStateStatus.getEnumByType(batchSegmentation.getState()));
        batchSegmentation.setFactoryName(factoryMap.get(batchSegmentation.getFactoryId()));
        batchSegmentation.setWorkshopName(workShopMap.get(batchSegmentation.getWorkshopId()));
        // todo 写死
        batchSegmentation.setPlanName("M660型PCB生产计划");
        return batchSegmentation;
    }

    /**
     * 分页查询
     *
     * @param batchSegmentation 筛选条件
     * @return 查询结果
     */
    @Override
    public List<BatchSegmentation> queryByPage(BatchSegmentationRequest batchSegmentation) {
        if (batchSegmentation.getMobileFlag() != null && batchSegmentation.getMobileFlag() && !SecurityUtils
                .getLoginUser()
                .getUser()
                .isAdmin()) {
//            dispatchList.setConductor(SecurityUtils.getLoginUser().getUserId());
        }
        Map<Long, String> factoryMap = queryFactoryMap();
        Map<Long, String> workShopMap = queryWorkShopMap();
        List<BatchSegmentation> batchSegmentations = segmentPageHelper(batchSegmentation);
        if (CollectionUtils.isEmpty(batchSegmentations)) {
            return batchSegmentations;
        }
        for (BatchSegmentation segmentation : batchSegmentations) {
            segmentation.setStateName(SegmentStateStatus.getEnumByType(segmentation.getState()));
            segmentation.setFactoryName(factoryMap.get(segmentation.getFactoryId()));
            segmentation.setWorkshopName(workShopMap.get(segmentation.getWorkshopId()));
            // todo  写死
            segmentation.setPlanName("M660型PCB生产计划");
        }
        return batchSegmentations;


    }

    private List<BatchSegmentation> segmentPageHelper(BatchSegmentationRequest batchSegmentation) {
        PageHelper.startPage(batchSegmentation.getCurrPage(), batchSegmentation.getPageSize());
        List<BatchSegmentation> batchSegmentations = this.batchSegmentationDao.queryAllByLimit(batchSegmentation);
        return batchSegmentations;
    }


    private Map<Long, String> queryFactoryMap() {
        Map factoryMap = new HashMap();
        List<FactoryVo> factoryVos = batchesDao.queryPlants();
        if (!CollectionUtils.isEmpty(factoryVos)) {
            for (FactoryVo factoryVo : factoryVos) {
                factoryMap.put(factoryVo.getId(), factoryVo.getPlantName());
            }
        }
        return factoryMap;
    }

    private Map<Long, String> queryWorkShopMap() {
        Map workShopMap = new HashMap();
        List<WorkshopVo> workshopVos = batchesDao.queryWorkshops();
        if (!CollectionUtils.isEmpty(workshopVos)) {
            for (WorkshopVo workshopVo : workshopVos) {
                workShopMap.put(workshopVo.getId(), workshopVo.getShopName());
            }
        }
        return workShopMap;
    }

    /**
     * 新增数据
     *
     * @param batchSegmentation 实例对象
     * @return 实例对象
     */
    @Override
    public BatchSegmentation insert(BatchSegmentation batchSegmentation) throws Exception {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        batchSegmentation.setCreatedBy(String.valueOf(loginUser.getUserId()));
        batchSegmentation.setCreatedDate(new Date());
        batchSegmentation.setLastModifiedDate(new Date());
        if (StrUtil.isEmpty(batchSegmentation.getBatchNumber())) {
            throw new Exception("批次编号不能为空");
        }
        BatchesRequest request = new BatchesRequest();
        request.setNumber(batchSegmentation.getBatchNumber());
        List<Batches> batches = batchesDao.batchesList(request);
        if (CollectionUtils.isEmpty(batches)) {
            throw new Exception("批次编号不存在:" + batchSegmentation.getBatchNumber());
        }
        Batches batch = batches.get(0);

        // 厂区 id
        batchSegmentation.setFactoryId(batch.getPlantId());
        // 批次ID
        batchSegmentation.setBatchId(batch.getId());
//        batchSegmentation.setBatchNumber(SerialNumberUtil.createSegmentNo());
        if (StrUtil.isEmpty(batchSegmentation.getSegmentName())) {
            throw new Exception("分段名称不能为空");
        }

        // 默认生产中
        batchSegmentation.setState(SegmentStateStatus.PENDING.getCode());
        this.batchSegmentationDao.insert(batchSegmentation);
        return batchSegmentation;
    }

    /**
     * 修改数据
     *
     * @param batchSegmentation 实例对象
     * @return 实例对象
     */
    @Override
    public BatchSegmentation update(BatchSegmentation batchSegmentation) throws Exception {
        if (StrUtil.isEmpty(batchSegmentation.getBatchNumber())) {
            throw new Exception("批次编号不能为空");
        }
        BatchesRequest request = new BatchesRequest();
        request.setNumber(batchSegmentation.getBatchNumber());
        List<Batches> batches = batchesDao.batchesList(request);
        if (CollectionUtils.isEmpty(batches)) {
            throw new Exception("批次编号不存在:" + batchSegmentation.getBatchNumber());
        }
        Batches batch = batches.get(0);
        // 厂区 id
        batchSegmentation.setFactoryId(batch.getPlantId());
        // 批次ID
        batchSegmentation.setBatchId(batch.getId());

        this.batchSegmentationDao.update(batchSegmentation);
        return this.queryById(batchSegmentation.getId());
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Long id) {
        BatchSegmentation batchSegmentation = batchSegmentationDao.queryById(id);
        if (batchSegmentation == null) {
            BatchesRequest batchesRequest = new BatchesRequest();
            batchesRequest.setId(id);
            // 删除批次
            return batchesDao.deleteBatches(batchesRequest) > 0;
        }
        // 删除分段
        return this.batchSegmentationDao.deleteById(id) > 0;
    }

    @Override
    public List<ProductionRecordResponse> queryList(BatchSegmentationRequest batchSegmentation) {
        ArrayList<ProductionRecordResponse> productionRecordResponses = new ArrayList<>();
        // 段号List信息
        List<BatchSegmentation> batchSegmentations = queryByPage(batchSegmentation);

        //批次信息List (分页)
        List<Batches> batches = batchesListPackage(batchSegmentation);
        if (CollectionUtils.isEmpty(batchSegmentations) || CollectionUtils.isEmpty(batches)) {
            return productionRecordResponses;
        }
        // 段号List转成Map key为批次id
        Map<Long, List<BatchSegmentation>> batchSegmentationsMap = batchSegmentationsToMap(batchSegmentations);
        for (Batches batch : batches) {
            if (!batchSegmentationsMap.containsKey(batch.getId())) {
                continue;
            }
            ProductionRecordResponse r = new ProductionRecordResponse();
            r.setBatchId(batch.getId());
            r.setBatchName(batch.getName());
            r.setBatchNumber(batch.getNumber());
            r.setEndDate(batch.getEndDate());
            r.setBeginDate(batch.getBeginDate());
            r.setBatchSegmentationInfos(batchSegmentationsMap.get(batch.getId()));
            r.setTime(batch.getTimeConsuming());
            productionRecordResponses.add(r);
        }
        return productionRecordResponses;
    }

    @Override
    public List<BatchSegmentationHead> getExportData(List<ProductionRecordResponse> list) {
        List<BatchSegmentationHead> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            return result;
        }
        for (ProductionRecordResponse batch : list) {
            List<BatchSegmentation> segmentationInfos = batch.getBatchSegmentationInfos();
            // 如果 batchSegmentationInfos 为空 TODO
            if (CollectionUtils.isEmpty(segmentationInfos)) {
                BatchSegmentationHead dto = new BatchSegmentationHead();
                BeanUtils.copyProperties(batch, dto);
                result.add(dto);
                continue;
            }
            for (BatchSegmentation batchSegmentationInfo : segmentationInfos) {
                BatchSegmentationHead dto = new BatchSegmentationHead();
                BeanUtils.copyProperties(batchSegmentationInfo, dto);
                BeanUtils.copyProperties(batch, dto);
                result.add(dto);
            }
        }
        return result;
    }


    /**
     * 段号List转成Map key为批次id
     *
     * @param batchSegmentations
     */
    private Map<Long, List<BatchSegmentation>> batchSegmentationsToMap(List<BatchSegmentation> batchSegmentations) {
        Map<Long, List<BatchSegmentation>> batchSegmentationMap = new HashMap<>();
        // 批次循环
        for (BatchSegmentation segmentation : batchSegmentations) {
            List<BatchSegmentation> arrayList = batchSegmentationMap.get(segmentation.getBatchId());
            if (CollectionUtils.isEmpty(arrayList)) {
                arrayList = new ArrayList<>();
            }
            arrayList.add(segmentation);
            if (segmentation.getBatchId() == null) {
                continue;
            }
            batchSegmentationMap.put(Long.valueOf(segmentation.getBatchId()), arrayList);
        }

        return batchSegmentationMap;
    }

    /**
     * 分页查询 批次
     *
     * @param batchSegmentation
     * @return
     */
    private List<Batches> batchesListPackage(BatchSegmentationRequest batchSegmentation) {
        BatchesRequest batchesRequest = new BatchesRequest();
        batchesRequest.setNumber(batchSegmentation.getBatchNumber());
        batchesRequest.setName(batchSegmentation.getBatchName());
        batchesRequest.setOrderNumber(batchSegmentation.getOrderNumber());
        /*if(!(batchSegmentation.getPageSize() == 0 &&  batchSegmentation.getPageSize() == 0 ) ){
            PageHelper.startPage(batchSegmentation.getCurrPage(), batchSegmentation.getPageSize());
        }*/
        return batchesDao.batchesList(batchesRequest);
    }


    @Override
    public Map<String, Long> productionRecordsChart(ProductionRecordsChartRequest request) {
        Map<String, Long> map = new HashMap<>();
        List<BatchSegmentation> batchSegmentations = batchSegmentationDao.productionRecordsList(request);
        if (!CollectionUtils.isEmpty(batchSegmentations)) {
            for (BatchSegmentation batchSegmentation : batchSegmentations) {
                map.put(batchSegmentation.getBatchNumber(), batchSegmentation.getBatchId());
            }
        }
        fillData(map, request.getDateType());
        return sortMap(map);
    }


    /**
     * 排序
     *
     * @param graph
     * @return
     */
    private Map<String, Long> sortMap(Map<String, Long> graph) {
        return graph
                .entrySet()
                .stream()
                .sorted(Map.Entry.comparingByKey())
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oleValue, newValue) -> oleValue, LinkedHashMap::new));
    }


    private void fillData(Map<String, Long> graph, Integer dateType) {

        int compare = 0;
        int beginIndex = 1;
        if (TimeDimensionEnum.DAY.getCode().equals(dateType)) {
            Calendar now = Calendar.getInstance();
            compare = now.getActualMaximum(Calendar.DAY_OF_MONTH);
        } else if (TimeDimensionEnum.MONTH.getCode().equals(dateType)) {
            compare = 24;
        } else if (TimeDimensionEnum.YEAR.getCode().equals(dateType)) {
            compare = 12;
        }
        for (int i = beginIndex; i <= compare; i++) {
            String key = String.valueOf(i);
            if (i < 10) {
                key = "0" + i;
            }
            if (!graph.containsKey(key)) {
                graph.put(key, 0L);
            }
        }


    }


    @Override
    public List<ProductionDict> stateList() {
        List<ProductionDict> list = new ArrayList<>();
        for (SegmentStateStatus item : SegmentStateStatus.values()) {
            ProductionDict productionDict = new ProductionDict();
            productionDict.setId(Long.valueOf(item.getCode()));
            productionDict.setName(item.getDesc());
            list.add(productionDict);
        }
        return list;
    }
}
